package com.security.it.authentication.mobile.sms;

import com.security.it.authentication.common.ValidateCodeProcessor;
import com.security.it.authentication.dto.ValidateCode;
import com.security.it.authentication.common.AbstractValidateCodeProcessor;
import com.security.it.authentication.exception.ValidateCodeException;
import com.security.it.core.constants.SecurityConstants;
import com.security.it.core.enums.ValidateCodeType;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;

import java.util.Objects;

@Component("smsCodeProcessor")
public class SmsCodeProcessor extends AbstractValidateCodeProcessor<ValidateCode> {
    @Autowired
    private SmsCodeSender smsCodeSender;

    private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();

    @Override
    protected void send(ServletWebRequest request, ValidateCode validateCode) throws Exception {
        String mobile = ServletRequestUtils.getStringParameter(request.getRequest(), SecurityConstants.LOGIN_PARAMETER_MOBILE);
        smsCodeSender.send(mobile, validateCode.getCode());
    }

    @Override
    public void validate(ServletWebRequest request) throws Exception {
        ValidateCode validateCode = (ValidateCode) sessionStrategy.getAttribute(request, getCodeSessionKey());
        String code = ServletRequestUtils.getStringParameter(request.getRequest(), SecurityConstants.LOGIN_VALIDATE_CODE_FROM_MOBILE);
        if (StringUtils.isBlank(code)) {
            throw new ValidateCodeException("验证码为空");
        }
        if (Objects.isNull(validateCode)) {
            throw new ValidateCodeException("验证码不存在");
        }
        if (validateCode.isExpired()) {
            sessionStrategy.removeAttribute(request, getCodeSessionKey());
            throw new ValidateCodeException("验证码已过期");
        }
        if (!StringUtils.equals(validateCode.getCode(), code)) {
            throw new ValidateCodeException("验证码错误");
        }
        sessionStrategy.removeAttribute(request, getCodeSessionKey());
    }

    @Override
    protected boolean accept(ValidateCodeType type) {
        return Objects.equals(ValidateCodeType.SMS, type);
    }

    /**
     * 获取请求验证码的类型
     */
    private String getCodeSessionKey() {
        return String.format(SecurityConstants.SESSION_KEY_PREFIX, ValidateCodeType.SMS.getCode().toUpperCase());
    }
}
